//
//  KLCurrencyService.m
//  KLCurrency
//
//  Created by apple on 2017/12/28.
//  Copyright © 2017年 bonc. All rights reserved.
//

#import "KLCurrencyService.h"

#import "KLDBHelper.h"
#import "KLCurrencyHelper.h"
#import "KLPlistHelper.h"
#import "KLCurrencyDAO.h"
#import "pinyin.h"

@implementation KLCurrencyService

+ (dispatch_queue_t)serviceQueue {
    static dispatch_queue_t service_queue;
    static dispatch_once_t serviceToken;
    dispatch_once(&serviceToken, ^{
        service_queue = dispatch_queue_create("currency.service.list", DISPATCH_QUEUE_SERIAL);
    });
    return service_queue;
}

#pragma mark - plist service
+ (BOOL)saveDefaultMainCurrencies {
    //创建默认显示货币
    NSArray *defaultMainCurrencies = [KLCurrencyHelper defaultMainCurrencyAbbreviation];
    BOOL success = [defaultMainCurrencies writeToFile:[KLPlistHelper mainCurrenciesPath] atomically:YES];
    return success;
}

+ (BOOL)saveMainCurrencies:(NSArray <NSString *>*)abbs {
    BOOL success = [abbs writeToFile:[KLPlistHelper mainCurrenciesPath] atomically:YES];
    return success;
}

+ (void)saveMainCurrencies:(NSArray<NSString *> *)abbs completion:(void (^)(void))completionHandler failure:(void (^)(NSString *))failureHandler {
    dispatch_async([[self class] serviceQueue], ^{
        BOOL success = [abbs writeToFile:[KLPlistHelper mainCurrenciesPath] atomically:YES];
        if (success) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (completionHandler) {
                    completionHandler();
                }
            });
        }else {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"plist update error");
                }
            });
        }
    });
}

+ (NSArray <NSString *>*)getMainCurrencies {
    NSString *fielPath = [KLPlistHelper mainCurrenciesPath];
    return [NSArray arrayWithContentsOfFile:fielPath];
}

+ (BOOL)saveDefaultExchangeRateDictionary {
    //创建默认rate
    NSDictionary *defaultExchangeRateDictionary = [KLCurrencyHelper defaultCurrencyExchangeRateDictionary];
    BOOL success = [defaultExchangeRateDictionary writeToFile:[KLPlistHelper exchangeRateDictionaryPath] atomically:YES];
    return success;
}

+ (BOOL)saveExchangeRateDictionary:(NSDictionary *)rateDictionary {
    BOOL success = [rateDictionary writeToFile:[KLPlistHelper exchangeRateDictionaryPath] atomically:YES];
    return success;
}

+ (void)saveExchangeRateDictionary:(NSDictionary *)rateDictionary completion:(void (^)(void))completionHandler failure:(void (^)(NSString *))failureHandler {
    dispatch_async([[self class] serviceQueue], ^{
        BOOL success = [rateDictionary writeToFile:[KLPlistHelper exchangeRateDictionaryPath] atomically:YES];
        if (success) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (completionHandler) {
                    completionHandler();
                }
            });
        }else {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"plist update error");
                }
            });
        }
    });
}

+ (NSDictionary *)getExchangeRateDictionary {
    NSString *fielPath = [KLPlistHelper exchangeRateDictionaryPath];
    return [NSDictionary dictionaryWithContentsOfFile:fielPath];
}

#pragma mark - db service
+ (long long)importDefaultCurrencies:(NSArray<KLCurrencyEntity *> *)currencies {
    FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
    if (![db open]) {
        return 0;
    }
    
    FMDatabaseQueue *dbQueue = [FMDatabaseQueue databaseQueueWithPath:[KLDBHelper dbPath]];
    __block long long currencyId = -1;
//    KLLog(@"mainThread - %@",[NSThread mainThread]);
    [dbQueue inTransaction:^(FMDatabase * _Nonnull db, BOOL * _Nonnull rollback) {
        for (NSUInteger i = 0; i < currencies.count; i++) {
            KLCurrencyEntity *currency = [currencies objectAtIndex:i];
            KLLog(@"name:%@", currency.name);
            currencyId = [KLCurrencyDAO insertModel:currency withDataBase:db];
//            KLLog(@"currentThread - %@",[NSThread currentThread]);
            if (currencyId == 0) {
                KLLog(@"break");
                *rollback = YES;
                break;
            }
        }
    }];
//    long long currencyId = -1;
//    for (NSUInteger i = 0; i < currencies.count; i++) {
//        KLCurrencyEntity *currency = [currencies objectAtIndex:i];
//
//        KLLog(@"name:%@", currency.name);
//
//        currencyId = [KLCurrencyDAO insertModel:currency withDataBase:db];
//        if (currencyId == 0) {
//            return 0;
//        }
//    }
    [db close];
    return currencyId;
}

+ (void)importDefaultCurrencies:(NSArray<KLCurrencyEntity *> *)currencies completion:(void (^)(long long))completionHandler failure:(void (^)(NSString *))failureHandler {
    dispatch_async([[self class] serviceQueue], ^{
        FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
        if (![db open]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"database open error");
                }
            });
        }
        
        FMDatabaseQueue *dbQueue = [FMDatabaseQueue databaseQueueWithPath:[KLDBHelper dbPath]];
        __block long long currencyId = -1;
        [dbQueue inTransaction:^(FMDatabase * _Nonnull db, BOOL * _Nonnull rollback) {
            for (NSUInteger i = 0; i < currencies.count; i++) {
                KLCurrencyEntity *currency = [currencies objectAtIndex:i];
                KLLog(@"name:%@", currency.name);
                currencyId = [KLCurrencyDAO insertModel:currency withDataBase:db];
                if (currencyId == 0) {
                    KLLog(@"break");
                    *rollback = YES;
                    break;
                }
            }
        }];
        [db close];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (completionHandler) {
                completionHandler(currencyId);
            }
        });
    });
}

+ (long long)getCountOfAllCurrencyEntities {
    FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
    if (![db open]) {
        return -1;
    }
    long long count = [KLCurrencyDAO queryModelCountWithDataBase:db];
    [db close];
    return count;
}

+ (void)getCountOfAllCurrencyEntitiesWithCompletion:(void (^)(long long))completionHandler failure:(void (^)(NSString *))failureHandler {
    dispatch_async([[self class] serviceQueue], ^{
        FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
        if (![db open]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"database open error");
                }
            });
        }
        long long count = [KLCurrencyDAO queryModelCountWithDataBase:db];
        [db close];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (completionHandler) {
                completionHandler(count);
            }
        });
    });
}

+ (NSArray<KLCurrencyEntity *> *)getMainCurrencyEntities {
    FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
    if (![db open]) {
        return 0;
    }
    NSArray *mainCurrencies = [[self class] getMainCurrencies];
    KLCurrencyEntity *model0 = [KLCurrencyDAO queryModelByAbbreviation:mainCurrencies[0] withDataBase:db];
    KLCurrencyEntity *model1 = [KLCurrencyDAO queryModelByAbbreviation:mainCurrencies[1] withDataBase:db];
    KLCurrencyEntity *model2 = [KLCurrencyDAO queryModelByAbbreviation:mainCurrencies[2] withDataBase:db];
    KLCurrencyEntity *model3 = [KLCurrencyDAO queryModelByAbbreviation:mainCurrencies[3] withDataBase:db];
    [db close];
    return @[model0,model1,model2,model3];
}

+ (void)getMainCurrencyEntitiesWithCompletion:(void (^)(NSArray<KLCurrencyEntity *> *))completionHandler failure:(void (^)(NSString *))failureHandler {
    dispatch_async([[self class] serviceQueue], ^{
        FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
        if (![db open]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"database open error");
                }
            });
        }
        NSArray *mainCurrencies = [[self class] getMainCurrencies];
        KLCurrencyEntity *model0 = [KLCurrencyDAO queryModelByAbbreviation:mainCurrencies[0] withDataBase:db];
        KLCurrencyEntity *model1 = [KLCurrencyDAO queryModelByAbbreviation:mainCurrencies[1] withDataBase:db];
        KLCurrencyEntity *model2 = [KLCurrencyDAO queryModelByAbbreviation:mainCurrencies[2] withDataBase:db];
        KLCurrencyEntity *model3 = [KLCurrencyDAO queryModelByAbbreviation:mainCurrencies[3] withDataBase:db];
        [db close];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (completionHandler) {
                completionHandler(@[model0,model1,model2,model3]);
            }
        });
    });
}

+ (NSArray<KLCurrencyEntity *> *)getCommonCurrencyEntities {
    FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
    if (![db open]) {
        return 0;
    }
    NSArray *currencys = [KLCurrencyDAO queryCommonModelsWithDataBase:db];
    [db close];
    
    return currencys;
}

+ (void)getCommonCurrencyEntitiesWithCompletion:(void (^)(NSArray<KLCurrencyEntity *> *))completionHandler failure:(void (^)(NSString *))failureHandler {
    dispatch_async([[self class] serviceQueue], ^{
        FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
        if (![db open]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"database open error");
                }
            });
        }
        NSArray *currencys = [KLCurrencyDAO queryCommonModelsWithDataBase:db];
        [db close];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (completionHandler) {
                completionHandler(currencys);
            }
        });
    });
}

+ (NSArray<KLCurrencyEntity *> *)getAllCurrencyEntities {
    FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
    if (![db open]) {
        return 0;
    }
    NSArray *currencys = [KLCurrencyDAO queryAllModelsWithDataBase:db];
    [db close];
    
    return currencys;
}

+ (void)getAllCurrencyEntitiesWithCompletion:(void (^)(NSArray<KLCurrencyEntity *> *))completionHandler failure:(void (^)(NSString *))failureHandler {
    dispatch_async([[self class] serviceQueue], ^{
        FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
        if (![db open]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"database open error");
                }
            });
        }
        NSArray *currencys = [KLCurrencyDAO queryAllModelsWithDataBase:db];
        [db close];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (completionHandler) {
                completionHandler(currencys);
            }
        });
    });
}

+ (NSArray<KLCurrencyGroup *> *)getAllCurrencyGroups {
    NSArray<KLCurrencyEntity *> *allArray = [KLCurrencyService getAllCurrencyEntities];
    NSMutableArray<KLCurrencyGroup *> *tempGroupArr = [NSMutableArray arrayWithCapacity:100];
    for (int i = 0; i<26; i++) {
        KLCurrencyGroup *group = [[KLCurrencyGroup alloc] init];
        NSMutableArray *items = [NSMutableArray array];
        group.group = [NSString stringWithFormat:@"%c",'A'+i];
        for (KLCurrencyEntity *item in allArray) {
            char first= pinyinFirstLetter([item.name characterAtIndex:0]);
            if ((first == ('a'+i) )||(first==  ('A'+i) )) {
                //                KLLog(@"00--%@",currencyInfoDic);
                [items addObject:item];
            }
        }
        group.currencies = [items mutableCopy];
        [tempGroupArr addObject:group];
    }
    //去除空的group
    NSMutableArray<KLCurrencyGroup *> *refreshArr = [NSMutableArray arrayWithCapacity:100];
    for (KLCurrencyGroup *group in tempGroupArr) {
        NSArray *currencies = group.currencies;
        if (currencies.count == 0 || currencies == nil) {
        }else {
            [refreshArr addObject:group];
        }
    }
    return [refreshArr mutableCopy];
}

+ (void)getAllCurrencyGroupsWithCompletion:(void (^)(NSArray<KLCurrencyGroup *> *))completionHandler failure:(void (^)(NSString *))failureHandler {
    [[self class] getAllCurrencyEntitiesWithCompletion:^(NSArray<KLCurrencyEntity *> *entities){
        NSMutableArray<KLCurrencyGroup *> *tempGroupArr = [NSMutableArray arrayWithCapacity:100];
        for (int i = 0; i<26; i++) {
            KLCurrencyGroup *group = [[KLCurrencyGroup alloc] init];
            NSMutableArray *items = [NSMutableArray array];
            group.group = [NSString stringWithFormat:@"%c",'A'+i];
            for (KLCurrencyEntity *item in entities) {
                char first= pinyinFirstLetter([item.name characterAtIndex:0]);
                if ((first == ('a'+i) )||(first==  ('A'+i) )) {
                    //                KLLog(@"00--%@",currencyInfoDic);
                    [items addObject:item];
                }
            }
            group.currencies = [items mutableCopy];
            [tempGroupArr addObject:group];
        }
        //去除空的group
        NSMutableArray<KLCurrencyGroup *> *refreshArr = [NSMutableArray arrayWithCapacity:100];
        for (KLCurrencyGroup *group in tempGroupArr) {
            NSArray *currencies = group.currencies;
            if (currencies.count == 0 || currencies == nil) {
            }else {
                [refreshArr addObject:group];
            }
        }
        
        if (completionHandler) {
            completionHandler([refreshArr mutableCopy]);
        }
    } failure:^(NSString *error) {
        if (failureHandler) {
            failureHandler(error);
        }
    }];
}

+ (NSArray<KLCurrencyEntity *> *)getFilteredCurrencyEntitiesWithSearchText:(NSString *)text {
    if ([text length]){
        FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
        if (![db open]) {
            return 0;
        }
        NSArray *currencys = [KLCurrencyDAO querySearchModelsWithSearchText:text withDataBase:db];
        [db close];
        return currencys;
    } else {
        return @[];
    }
}

+ (void)getFilteredCurrencyEntitiesWithSearchText:(NSString *)text completion:(void (^)(NSArray<KLCurrencyEntity *> *))completionHandler failure:(void (^)(NSString *))failureHandler {
    dispatch_async([[self class] serviceQueue], ^{
        NSArray<KLCurrencyEntity *> *currencys;
        if ([text length]){
            FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
            if (![db open]) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (failureHandler) {
                        failureHandler(@"database open error");
                    }
                });
            }
            currencys = [KLCurrencyDAO querySearchModelsWithSearchText:text withDataBase:db];
            [db close];
        } else {
            currencys = @[];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            if (completionHandler) {
                completionHandler(currencys);
            }
        });
    });
}

+ (BOOL)convertOldMainCurrency:(KLCurrencyEntity *)oldMainCurrency toNewMainCurrency:(KLCurrencyEntity *)newMainCurrency{
    FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
    if (![db open]) {
        return NO;
    }
    BOOL success0 = NO;
    BOOL success1 = NO;
    BOOL success2 = NO;
    success0 = [KLCurrencyDAO updateModelWithAbbreviation:oldMainCurrency.abbreviation mainValue:NO withDataBase:db];
    if (success0) {
        success1 = [KLCurrencyDAO updateModelWithAbbreviation:newMainCurrency.abbreviation mainValue:YES withDataBase:db];
        if (success1) {
            success2 = [KLCurrencyDAO updateModelWithAbbreviation:newMainCurrency.abbreviation commonValue:YES withDataBase:db];
        }
    }
    [db close];
    return success2;
}

+ (void)convertOldMainCurrency:(KLCurrencyEntity *)oldMainCurrency toNewMainCurrency:(KLCurrencyEntity *)newMainCurrency completion:(void (^)(void))completionHandler failure:(void (^)(NSString *))failureHandler {
    dispatch_async([[self class] serviceQueue], ^{
        FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
        if (![db open]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"database open error");
                }
            });
        }
        BOOL success0 = NO;
        BOOL success1 = NO;
        BOOL success2 = NO;
        success0 = [KLCurrencyDAO updateModelWithAbbreviation:oldMainCurrency.abbreviation mainValue:NO withDataBase:db];
        if (success0) {
            success1 = [KLCurrencyDAO updateModelWithAbbreviation:newMainCurrency.abbreviation mainValue:YES withDataBase:db];
            if (success1) {
                success2 = [KLCurrencyDAO updateModelWithAbbreviation:newMainCurrency.abbreviation commonValue:YES withDataBase:db];
            }
        }
        [db close];
        if (success2) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (completionHandler) {
                    completionHandler();
                }
            });
        }else {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"table update error");
                }
            });
        }
    });
}

+ (BOOL)deleteCommonCurrency:(KLCurrencyEntity *)currency {
    FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
    if (![db open]) {
        return NO;
    }
    BOOL success = [KLCurrencyDAO updateModelWithAbbreviation:currency.abbreviation commonValue:NO withDataBase:db];
    [db close];
    return success;
}

+ (void)deleteCommonCurrency:(KLCurrencyEntity *)currency completion:(void (^)(void))completionHandler failure:(void (^)(NSString *))failureHandler {
    dispatch_async([[self class] serviceQueue], ^{
        FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
        if (![db open]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"database open error");
                }
            });
        }
        BOOL success = [KLCurrencyDAO updateModelWithAbbreviation:currency.abbreviation commonValue:NO withDataBase:db];
        [db close];
        if (success) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (completionHandler) {
                    completionHandler();
                }
            });
        }else {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (failureHandler) {
                    failureHandler(@"table update error");
                }
            });
        }
    });
}



//更新本地货币
+ (BOOL)updateLocalCurrencyWithLocation:(NSString *)location{
    FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
    if (![db open]) {
        return NO;
    }
    KLCurrencyEntity *model = [KLCurrencyDAO queryModelByNation:location withDataBase:db];
    //查询输入货币是否是本地货币
    if (model.local == NO) {
        //更新本地货币
        
        BOOL success0 = NO; //移除旧货币
        BOOL success1 = NO; //增加新货币
        NSString *oldNation = kDefaultLocalCurrencyNation;
        
        NSArray *currencys = [KLCurrencyDAO queryLocalModelsWithDataBase:db];
        if ([currencys firstObject]) {
            KLCurrencyEntity *entity =  currencys.firstObject;
            oldNation = entity.nation;
        }
        success0 = [KLCurrencyDAO updateModelWithNation:oldNation localValue:NO withDataBase:db];
        if (success0) {
            success1 = [KLCurrencyDAO updateModelWithNation:location localValue:YES withDataBase:db];
        }
        [db close];
        return success1;
    } else {
        [db close];
        return YES;
    }
}

+ (NSString *)getLocalCurrencyAbbr {
    FMDatabase *db = [FMDatabase databaseWithPath:[KLDBHelper dbPath]];
    if (![db open]) {
        return kDefaultLocalCurrencyAbbr;
    }
    NSArray *currencys = [KLCurrencyDAO queryLocalModelsWithDataBase:db];
    if ([currencys firstObject]) {
        KLCurrencyEntity *entity =  currencys.firstObject;
        return entity.abbreviation;
    }
    return kDefaultLocalCurrencyAbbr;
}

@end
